```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Java HashMap 原理深度解析</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Hiragino Sans GB", Simsun, sans-serif;
            line-height: 1.8;
            color: #333;
            background-color: #f9fafb;
        }
        .heading {
            font-family: 'Noto Serif SC', serif;
        }
        .drop-cap::first-letter {
            float: left;
            font-size: 3.5em;
            line-height: 0.8;
            margin: 0.1em 0.1em 0.1em 0;
            color: #4f46e5;
            font-weight: 700;
        }
        .code-block {
            background-color: #f8fafc;
            border-left: 4px solid #4f46e5;
            border-radius: 0.375rem;
            overflow-x: auto;
        }
        .code-block pre {
            margin: 0;
            padding: 1rem;
            font-family: 'Consolas', 'Monaco', 'Andale Mono', 'Ubuntu Mono', monospace;
        }
        .card {
            transition: all 0.3s ease;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(0,0,0,0.1);
        }
        .timeline-item::before {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            height: 100%;
            width: 2px;
            background: #4f46e5;
        }
        .highlight {
            background: linear-gradient(90deg, rgba(79,70,229,0.1) 0%, rgba(79,70,229,0) 100%);
            border-left: 3px solid #4f46e5;
            padding: 0.5rem 1rem;
            margin: 1rem 0;
        }
    </style>
</head>
<body class="min-h-screen flex flex-col">
    <!-- Hero Section -->
    <header class="relative bg-gradient-to-r from-indigo-600 to-purple-600 text-white py-20">
        <div class="container mx-auto px-6 flex flex-col items-center text-center">
            <h1 class="heading text-5xl font-bold mb-6">Java HashMap 原理深度解析</h1>
            <p class="text-xl max-w-3xl opacity-90 mb-8">探索 Java 中最常用的哈希表实现，揭秘其高效数据存储与检索的奥秘</p>
            <div class="flex space-x-4">
                <a href="#process" class="px-6 py-3 bg-white text-indigo-600 rounded-lg font-medium hover:bg-opacity-90 transition-all transform hover:-translate-y-1">
                    <i class="fas fa-arrow-down mr-2"></i>插入过程
                </a>
                <a href="#analysis" class="px-6 py-3 bg-transparent border-2 border-white rounded-lg font-medium hover:bg-white hover:text-indigo-600 transition-all transform hover:-translate-y-1">
                    <i class="fas fa-code mr-2"></i>源码分析
                </a>
            </div>
        </div>
        <div class="absolute bottom-0 left-0 right-0 h-16 bg-white transform skew-y-1 -mb-8"></div>
    </header>

    <!-- Main Content -->
    <main class="flex-grow container mx-auto px-6 py-12">
        <!-- Intro -->
        <section class="max-w-4xl mx-auto mb-16">
            <p class="drop-cap text-lg text-gray-700 mb-6">HashMap 是 Java 集合框架中最重要且最常用的数据结构之一，它提供了高效的键值对存储和检索能力。理解 HashMap 的内部工作原理对于编写高效、可靠的 Java 代码至关重要。</p>
            
            <div class="grid md:grid-cols-2 gap-8 my-10">
                <div class="card bg-white p-6 rounded-xl">
                    <div class="flex items-center mb-4">
                        <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center text-indigo-600 mr-4">
                            <i class="fas fa-bolt text-xl"></i>
                        </div>
                        <h3 class="heading text-xl font-semibold">O(1) 时间复杂度</h3>
                    </div>
                    <p class="text-gray-600">在理想情况下，HashMap 的 get 和 put 操作都能达到常数时间复杂度，这使其成为快速查找的理想选择。</p>
                </div>
                <div class="card bg-white p-6 rounded-xl">
                    <div class="flex items-center mb-4">
                        <div class="w-10 h-10 rounded-full bg-purple-100 flex items-center justify-center text-purple-600 mr-4">
                            <i class="fas fa-project-diagram text-xl"></i>
                        </div>
                        <h3 class="heading text-xl font-semibold">链表与红黑树</h3>
                    </div>
                    <p class="text-gray-600">Java 8 引入了红黑树来优化哈希冲突处理，当链表长度超过阈值(默认8)时会转换为红黑树。</p>
                </div>
            </div>
        </section>

        <!-- Process Section -->
        <section id="process" class="max-w-4xl mx-auto mb-16">
            <h2 class="heading text-3xl font-bold mb-8 text-center text-gray-800">
                <i class="fas fa-sitemap mr-3 text-indigo-600"></i>
                HashMap 插入数据的过程
            </h2>

            <div class="relative">
                <!-- Timeline -->
                <div class="space-y-10">
                    <!-- Step 1 -->
                    <div class="timeline-item pl-8 relative">
                        <div class="absolute -left-8 top-0 w-6 h-6 rounded-full bg-indigo-600 flex items-center justify-center text-white">
                            <span class="text-xs font-bold">1</span>
                        </div>
                        <div class="bg-white p-6 rounded-lg shadow-sm">
                            <h3 class="heading text-xl font-semibold mb-4 text-indigo-600">计算哈希值</h3>
                            <div class="code-block mb-4">
                                <pre><code class="text-sm">int hash = hash(key.hashCode());</code></pre>
                            </div>
                            <p class="text-gray-700">HashMap 使用键的 <code>hashCode()</code> 方法计算哈希值，然后通过扰动函数进一步处理以减少冲突。</p>
                            <div class="highlight mt-4">
                                <p class="text-gray-700 font-medium">Java 8 扰动函数：</p>
                                <div class="code-block mt-2">
                                    <pre><code class="text-sm">final int hash = (key == null) ? 0 : (h ^ (h >>> 16));</code></pre>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- Step 2 -->
                    <div class="timeline-item pl-8 relative">
                        <div class="absolute -left-8 top-0 w-6 h-6 rounded-full bg-indigo-600 flex items-center justify-center text-white">
                            <span class="text-xs font-bold">2</span>
                        </div>
                        <div class="bg-white p-6 rounded-lg shadow-sm">
                            <h3 class="heading text-xl font-semibold mb-4 text-indigo-600">确定索引</h3>
                            <div class="code-block mb-4">
                                <pre><code class="text-sm">int index = (n - 1) & hash; // n 是数组的长度</code></pre>
                            </div>
                            <p class="text-gray-700">通过哈希值与数组长度取模运算确定键值对在内部数组中的存储位置。HashMap 内部数组长度总是2的幂次方，这使得取模运算可以优化为位运算。</p>
                        </div>
                    </div>

                    <!-- Step 3 -->
                    <div class="timeline-item pl-8 relative">
                        <div class="absolute -left-8 top-0 w-6 h-6 rounded-full bg-indigo-600 flex items-center justify-center text-white">
                            <span class="text-xs font-bold">3</span>
                        </div>
                        <div class="bg-white p-6 rounded-lg shadow-sm">
                            <h3 class="heading text-xl font-semibold mb-4 text-indigo-600">检查并处理冲突</h3>
                            <div class="code-block mb-4">
                                <pre><code class="text-sm">Node&lt;K,V&gt; e;
if ((e = tab[i]) == null) {
    tab[i] = newNode(hash, key, value, null);
} else {
    // 处理冲突，链表或树结构
    if (e.hash == hash && (e.key == key || key.equals(e.key))) {
        e.value = value;
    } else {
        // 链表处理或转换为树结构
    }
}</code></pre>
                            </div>
                            <p class="text-gray-700">如果目标位置为空，则直接插入；否则需要处理哈希冲突。Java 8 之前使用链表处理冲突，Java 8 之后当链表长度超过阈值(默认8)时会转换为红黑树以提高性能。</p>
                        </div>
                    </div>

                    <!-- Step 4 -->
                    <div class="timeline-item pl-8 relative">
                        <div class="absolute -left-8 top-0 w-6 h-6 rounded-full bg-indigo-600 flex items-center justify-center text-white">
                            <span class="text-xs font-bold">4</span>
                        </div>
                        <div class="bg-white p-6 rounded-lg shadow-sm">
                            <h3 class="heading text-xl font-semibold mb-4 text-indigo-600">调整容量</h3>
                            <div class="code-block mb-4">
                                <pre><code class="text-sm">if (size > threshold) {
    resize();
}</code></pre>
                            </div>
                            <p class="text-gray-700">当元素数量达到负载因子(默认0.75)和当前容量的乘积时，HashMap 会触发扩容操作。扩容会创建新数组(通常是原数组长度的两倍)并重新计算所有元素的位置。</p>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Visualization -->
        <section class="max-w-4xl mx-auto mb-16 bg-white p-8 rounded-xl shadow-sm">
            <h2 class="heading text-3xl font-bold mb-8 text-center text-gray-800">
                <i class="fas fa-chart-network mr-3 text-purple-600"></i>
                HashMap 数据结构可视化
            </h2>
            
            <div class="mermaid">
                graph TD
                    A[HashMap] --> B[数组]
                    B --> B1[索引0]
                    B --> B2[索引1]
                    B --> B3[索引2]
                    B --> B4[...]
                    B1 --> C1[Node1]
                    C1 --> C2[Node2]
                    C2 --> C3[Node3]
                    B2 --> D1[TreeNode1]
                    D1 --> D2[TreeNode2]
                    D2 --> D3[TreeNode3]
                    D2 --> D4[TreeNode4]
                    
                    style A fill:#4f46e5,color:white
                    style B fill:#f0f9ff,stroke:#4f46e5
                    style B1 fill:#f0f9ff,stroke:#4f46e5
                    style B2 fill:#f0f9ff,stroke:#4f46e5
                    style B3 fill:#f0f9ff,stroke:#4f46e5
                    style B4 fill:#f0f9ff,stroke:#4f46e5
                    style C1 fill:#e0e7ff,stroke:#4f46e5
                    style C2 fill:#e0e7ff,stroke:#4f46e5
                    style C3 fill:#e0e7ff,stroke:#4f46e5
                    style D1 fill:#ede9fe,stroke:#8b5cf6
                    style D2 fill:#ede9fe,stroke:#8b5cf6
                    style D3 fill:#ede9fe,stroke:#8b5cf6
                    style D4 fill:#ede9fe,stroke:#8b5cf6
            </div>
            <div class="mt-6 grid md:grid-cols-2 gap-4">
                <div class="p-4 bg-indigo-50 rounded-lg">
                    <div class="flex items-center mb-2">
                        <div class="w-4 h-4 rounded-full bg-indigo-500 mr-2"></div>
                        <span class="text-sm font-medium">数组 + 链表结构</span>
                    </div>
                    <p class="text-sm text-gray-600">Java 8 之前的实现方式，当哈希冲突时使用链表存储</p>
                </div>
                <div class="p-4 bg-purple-50 rounded-lg">
                    <div class="flex items-center mb-2">
                        <div class="w-4 h-4 rounded-full bg-purple-500 mr-2"></div>
                        <span class="text-sm font-medium">数组 + 红黑树</span>
                    </div>
                    <p class="text-sm text-gray-600">Java 8 引入的优化，当链表长度超过阈值时转换为红黑树</p>
                </div>
            </div>
        </section>

        <!-- Source Code Analysis -->
        <section id="analysis" class="max-w-4xl mx-auto mb-16">
            <h2 class="heading text-3xl font-bold mb-8 text-center text-gray-800">
                <i class="fas fa-file-code mr-3 text-indigo-600"></i>
                源码分析
            </h2>
            
            <div class="bg-white p-8 rounded-xl shadow-sm">
                <div class="code-block mb-8">
                    <pre><code class="text-sm">public V put(K key, V value) {
    // 计算哈希值
    int hash = hash(key.hashCode());
    // 计算索引
    int i = indexFor(hash, table.length);
    
    // 检查位置是否为空
    for (Node&lt;K,V&gt; e = table[i]; e != null; e = e.next) {
        // 如果存在相同键，则更新值
        if (e.hash == hash && (e.key == key || key.equals(e.key))) {
            V oldValue = e.value;
            e.value = value;
            return oldValue;
        }
    }
    
    // 如果位置为空，则插入新节点
    addNode(hash, key, value, i);
    return null;
}

private void addNode(int hash, K key, V value, int index) {
    // 插入新的节点
    Node&lt;K,V&gt; p = table[index];
    table[index] = new Node&lt;&gt;(hash, key, value, p);
    
    // 检查是否需要扩容
    if (++size > threshold) {
        resize();
    }
}</code></pre>
                </div>
                
                <div class="grid md:grid-cols-2 gap-6">
                    <div>
                        <h3 class="heading text-xl font-semibold mb-4 text-indigo-600">
                            <i class="fas fa-check-circle mr-2"></i>
                            关键点
                        </h3>
                        <ul class="space-y-3">
                            <li class="flex items-start">
                                <i class="fas fa-check text-indigo-500 mt-1 mr-2"></i>
                                <span class="text-gray-700">哈希计算和索引确定是核心操作</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check text-indigo-500 mt-1 mr-2"></i>
                                <span class="text-gray-700">先检查是否存在相同键，存在则更新值</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check text-indigo-500 mt-1 mr-2"></i>
                                <span class="text-gray-700">插入新节点时采用头插法</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check text-indigo-500 mt-1 mr-2"></i>
                                <span class="text-gray-700">插入后检查是否需要扩容</span>
                            </li>
                        </ul>
                    </div>
                    <div>
                        <h3 class="heading text-xl font-semibold mb-4 text-purple-600">
                            <i class="fas fa-lightbulb mr-2"></i>
                            性能考虑
                        </h3>
                        <ul class="space-y-3">
                            <li class="flex items-start">
                                <i class="fas fa-bolt text-purple-500 mt-1 mr-2"></i>
                                <span class="text-gray-700">好的哈希函数可以减少冲突</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-bolt text-purple-500 mt-1 mr-2"></i>
                                <span class="text-gray-700">初始容量和负载因子的合理设置</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-bolt text-purple-500 mt-1 mr-2"></i>
                                <span class="text-gray-700">Java 8 的红黑树优化极端情况</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-bolt text-purple-500 mt-1 mr-2"></i>
                                <span class="text-gray-700">键对象的不可变性有助于保持一致性</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>

        <!-- Summary -->
        <section class="max-w-4xl mx-auto mb-16">
            <h2 class="heading text-3xl font-bold mb-8 text-center text-gray-800">
                <i class="fas fa-clipboard-check mr-3 text-indigo-600"></i>
                总结
            </h2>
            
            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-indigo-50 p-6 rounded-xl">
                    <h3 class="heading text-xl font-semibold mb-4 text-indigo-600">
                        <i class="fas fa-plus-circle mr-2"></i>
                        插入过程要点
                    </h3>
                    <ul class="space-y-3 text-gray-700">
                        <li class="flex items-start">
                            <div class="flex-shrink-0 h-6 w-6 rounded-full bg-indigo-100 flex items-center justify-center text-indigo-600 mr-3">
                                <i class="fas fa-hashtag text-xs"></i>
                            </div>
                            <span>通过 <code>hashCode()</code> 计算哈希值并使用扰动函数减少冲突</span>
                        </li>
                        <li class="flex items-start">
                            <div class="flex-shrink-0 h-6 w-6 rounded-full bg-indigo-100 flex items-center justify-center text-indigo-600 mr-3">
                                <i class="fas fa-map-marker-alt text-xs"></i>
                            </div>
                            <span>哈希值映射到数组索引确定存储位置</span>
                        </li>
                        <li class="flex items-start">
                            <div class="flex-shrink-0 h-6 w-6 rounded-full bg-indigo-100 flex items-center justify-center text-indigo-600 mr-3">
                                <i class="fas fa-link text-xs"></i>
                            </div>
                            <span>冲突时使用链表或红黑树存储</span>
                        </li>
                        <li class="flex items-start">
                            <div class="flex-shrink-0 h-6 w-6 rounded-full bg-indigo-100 flex items-center justify-center text-indigo-600 mr-3">
                                <i class="fas fa-expand text-xs"></i>
                            </div>
                            <span>当元素数量达到阈值时自动扩容</span>
                        </li>
                    </ul>
                </div>
                
                <div class="bg-purple-50 p-6 rounded-xl">
                    <h3 class="heading text-xl font-semibold mb-4 text-purple-600">
                        <i class="fas fa-chart-line mr-2"></i>
                        性能特性
                    </h3>
                    <ul class="space-y-3 text-gray-700">
                        <li class="flex items-start">
                            <div class="flex-shrink-0 h-6 w-6 rounded-full bg-purple-100 flex items-center justify-center text-purple-600 mr-3">
                                <i class="fas fa-stopwatch text-xs"></i>
                            </div>
                            <span>平均情况下 get 和 put 操作的时间复杂度为 O(1)</span>
                        </li>
                        <li class="flex items-start">
                            <div class="flex-shrink-0 h-6 w-6 rounded-full bg-purple-100 flex items-center justify-center text-purple-600 mr-3">
                                <i class="fas fa-sitemap text-xs"></i>
                            </div>
                            <span>最坏情况下(大量冲突)时间复杂度为 O(log n)</span>
                        </li>
                        <li class="flex items-start">
                            <div class="flex-shrink-0 h-6 w-6 rounded-full bg-purple-100 flex items-center justify-center text-purple-600 mr-3">
                                <i class="fas fa-memory text-xs"></i>
                            </div>
                            <span>空间复杂度为 O(n)</span>
                        </li>
                        <li class="flex items-start">
                            <div class="flex-shrink-0 h-6 w-6 rounded-full bg-purple-100 flex items-center justify-center text-purple-600 mr-3">
                                <i class="fas fa-tachometer-alt text-xs"></i>
                            </div>
                            <span>扩容操作代价较高，应合理设置初始容量</span>
                        </li>
                    </ul>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-8">
        <div class="container mx-auto px-6 text-center">
            <div class="mb-4">
                <a href="http://www.yuque.com/jtostring" class="text-white hover:text-indigo-300 transition-colors font-medium">
                    技术小馆
                </a>
            </div>
            <div>
                <a href="http://www.yuque.com/jtostring" class="text-sm hover:text-indigo-300 transition-colors">
                    <i class="fas fa-globe mr-1"></i> http://www.yuque.com/jtostring
                </a>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```